﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BusinessObjects;
using DataObjects.EntityFramework.ModelMapper;

using System.Linq.Dynamic;

namespace DataObjects.EntityFramework.Implementation
{
    /// <summary>
    /// Entity Framework implementation of the IProductDao interface.
    /// </summary>
    public class EntityProductDao : IProductDao
    {
        /// <summary>
        /// Gets a product given a product identifier.
        /// </summary>
        /// <param name="productId">Product identifier.</param>
        /// <returns>The product.</returns>
        public Product GetProduct(int productId,int categoryId)
        {
            using (var context = DataObjectFactory.CreateContext())
            {
                return Mapper.Map(context.ProductEntities.SingleOrDefault(p => ((p.ProductId == productId) && (p.CategoryId == categoryId))));
            }
        }

        /// <summary>
        /// Gets list of product categories for a given category.
        /// </summary>
        /// <param name="categoryId">The category for which products are requested.</param>
        /// <param name="sortExpression">Sort order.</param>
        /// <returns>List of products.</returns>
        public List<Product> GetProductsByCategory(int categoryId, string sortExpression)
        {
            using (var context = DataObjectFactory.CreateContext()) 
            {
                // Load single Category with all Product child records
                var category = context.CategoryEntities.Include("Products").FirstOrDefault(c => c.CategoryId == categoryId);

                // Order by (using dynamic linq) without going back to db
                var products = category.Products.AsQueryable().OrderBy(sortExpression, null); 
                
                // Return list of business objects
                return products.Select(p => Mapper.Map(p)).ToList();
            }
        }

        public List<Product> SearchProducts(int categoryId, string sortExpression)
        {
            using (var context = DataObjectFactory.CreateContext())
            {
                var query = context.ProductEntities.AsQueryable();
                query = query.Where(p => p.CategoryId == categoryId);

                var products = query.OrderBy(sortExpression, null).ToList();

                return products.Select(p => Mapper.Map(p)).ToList();
            }
        }


        /// <summary>
        /// Inserts a new product record to the database.
        /// </summary>
        /// <param name="product">The productto be inserted.</param>
        public void InsertProduct(Product product)
        {
            var entity = Mapper.Map(product);

            using (var context = DataObjectFactory.CreateContext())
            {
                context.ProductEntities.AddObject(entity);
                context.SaveChanges();

                // update business object with new version and id                
                product.ProductId= entity.ProductId;

                //product.Version = Convert.ToBase64String(entity.Version);
            }
        }

        //Will be continue customizetion for Product by PHAN MINH TAI
        /// <summary>
        /// Updates a customer record in the database.
        /// </summary>
        /// <param name="customer">The customer with updated values.</param>
        /// <returns>Number of rows affected.</returns>
        public void UpdateProduct(Product product)
        {
            using (var context = DataObjectFactory.CreateContext())
            {
                var entity = context.ProductEntities.Where(c => c.ProductId == product.ProductId).SingleOrDefault();
                //vietnh
                //entity.ProductName = product.ProductName;
                entity.Status = product.Status;
                entity.UnitPrice = (decimal)product.UnitPrice;
                //entity.Weight = product.Weight;
                //vietnh
                context.ProductEntities.ApplyCurrentValues(entity);
                context.SaveChanges();

                // Update business object with new version
                product.Version = Convert.ToBase64String(entity.Version);
            }
        }


        //Will be continue customizetion for Product by PHAN MINH TAI
        /// <summary>
        /// Updates a product status record in the database.
        /// </summary>
        /// <param name="customer">The customer with updated values.</param>
        /// <returns>Number of rows affected.</returns>
        public void Book(int productId, int statusId)
        {
            using (var context = DataObjectFactory.CreateContext())
            {
                var entity = context.ProductEntities.Where(c => c.ProductId == productId).SingleOrDefault();
                entity.Status = statusId;

                context.ProductEntities.ApplyCurrentValues(entity);
                context.SaveChanges();                
            }
        }
        /// <summary>
        /// Deletes a customer record from the database.
        /// </summary>
        /// <param name="customer">The customer to be deleted.</param>
        /// <returns>Number of rows affected.</returns>
        public void DeleteProduct(Product product)
        {
            using (var context = DataObjectFactory.CreateContext())
            {
                var entity = context.ProductEntities.Where(c => c.ProductId == product.ProductId).SingleOrDefault();
                context.ProductEntities.DeleteObject(entity);
                context.SaveChanges();
            }
        }

        public void DeleteProductByCategoryId(int categoryId)
        {
            using (var context = DataObjectFactory.CreateContext())
            {
                var entity = context.ProductEntities.Where(p => p.CategoryId == categoryId).SingleOrDefault();
                context.ProductEntities.DeleteObject(entity);
                context.SaveChanges();
            }
        }

    }
}
